package com.huawei.cloud.phone.management.domain.user;

import com.huawei.cloud.phone.management.common.BeanFactory;
import com.huawei.cloud.phone.management.common.GlobalConfig;
import com.huawei.cloud.phone.management.common.RandomStringUtils;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.lang.NonNull;

import java.io.Serializable;
import java.util.function.Predicate;

@NoArgsConstructor
@Data
public class LoginInfo implements Serializable {
    static final long serialVersionUID = -7034897190745766111L;

    private String ticket;

    private String aesKey;

    private Long authTs;

    private Integer backgroundTimeout;

    private Integer availablePlayTime;

    private Integer touchTimeout;

    private String userId;

    public LoginInfo(String userId) {
        this.userId = userId;
        this.ticket = RandomStringUtils.randomString(256);
        this.aesKey = RandomStringUtils.randomAes128Key();
        this.authTs = System.currentTimeMillis();
        GlobalConfig globalConfig = BeanFactory.getBean(GlobalConfig.class);
        this.backgroundTimeout = globalConfig.getBackgroundTimeout();
        this.availablePlayTime = globalConfig.getAvailablePlayTime();
        this.touchTimeout = globalConfig.getTouchTimeout();
    }

    /**
     * 校验登录信息
     *
     * @param loginInfo 登录信息
     */
    public void check(@NonNull LoginInfo loginInfo) {
        if (!equalWithoutNull(loginInfo)) {
            throw new RuntimeException("login info check failed.");
        }
    }

    /**
     * 校验ticket信息
     *
     * @param ticket ticket信息
     */
    public void check(String ticket) {
        if (!equalWithoutNull(this.ticket, ticket)) {
            throw new RuntimeException("login info check failed.");
        }
    }

    private boolean equalWithoutNull(LoginInfo loginInfo) {
        Predicate<LoginInfo> predicate = data -> equalWithoutNull(this.ticket, data.getTicket());
        predicate = predicate.or(data -> equalWithoutNull(this.aesKey, data.getAesKey()))
                .or(data -> equalWithoutNull(this.authTs, data.getAuthTs()))
                .or(data -> equalWithoutNull(this.backgroundTimeout, data.getBackgroundTimeout()))
                .or(data -> equalWithoutNull(this.availablePlayTime, data.getAvailablePlayTime()))
                .or(data -> equalWithoutNull(this.touchTimeout, data.getTouchTimeout()))
                .or(data -> equalWithoutNull(this.userId, data.getUserId()));
        return predicate.test(loginInfo);
    }

    private boolean equalWithoutNull(Object origin, Object target) {
        return ObjectUtils.anyNull(origin, target) || origin.equals(target);
    }
}
